#include "stdafx.h"

static const char* vdsCode( HRESULT hr )
{
	static CAtlMap<HRESULT, const char*> messages;

	if( messages.GetCount() <= 0 )
	{
		messages[ VDS_E_NOT_SUPPORTED ] = "The operation is not supported by the object.";
		messages[ VDS_E_INITIALIZED_FAILED ] = "The service failed to initialize.";
		messages[ VDS_E_INITIALIZE_NOT_CALLED ] = "The initialization method was not called.";
		messages[ VDS_E_ALREADY_REGISTERED ] = "The provider is already registered.";
		messages[ VDS_E_ANOTHER_CALL_IN_PROGRESS ] = "A concurrent second call is made on an object before the first is completed.";
		messages[ VDS_E_OBJECT_NOT_FOUND ] = "The object is not found.";
		messages[ VDS_E_INVALID_SPACE ] = "The specified space is not free or not valid.";
		messages[ VDS_E_PARTITION_LIMIT_REACHED ] = "The number of partitions has reached the limit on a disk.";
		messages[ VDS_E_PARTITION_NOT_EMPTY ] = "The extended partition is not empty.";
		messages[ VDS_E_OPERATION_PENDING ] = "The operation has not been completed yet.";
		messages[ VDS_E_OPERATION_DENIED ] = "This operation is not allowed on the current boot, system or pagefile volume. It is also not allowed on any volume on a basic MBR disk that contains the boot, system or pagefile volume.";
		messages[ VDS_E_OBJECT_DELETED ] = "The object has been deleted.";
		messages[ VDS_E_CANCEL_TOO_LATE ] = "The operation cannot be canceled.";
		messages[ VDS_E_OPERATION_CANCELED ] = "The operation has been canceled.";
		messages[ VDS_E_CANNOT_EXTEND ] = "The volume cannot be extended because the file system does not support it.";
		messages[ VDS_E_NOT_ENOUGH_SPACE ] = "There is not enough usable space for this operation.";
		messages[ VDS_E_NOT_ENOUGH_DRIVE ] = "Not enough drives are specified to complete this operation.";
		messages[ VDS_E_BAD_COOKIE ] = "The cookie is not found.";
		messages[ VDS_E_NO_MEDIA ] = "There is no media in the device.";
		messages[ VDS_E_DEVICE_IN_USE ] = "The device is in use.";
		messages[ VDS_E_DISK_NOT_EMPTY ] = "The disk is not empty.";
		messages[ VDS_E_INVALID_OPERATION ] = "Invalid operation.";
		messages[ VDS_E_PATH_NOT_FOUND ] = "The path is not found.";
		messages[ VDS_E_DISK_NOT_INITIALIZED ] = "The disk is not initialized.";
		messages[ VDS_E_NOT_AN_UNALLOCATED_DISK ] = "The disk is not unallocated.";
		messages[ VDS_E_UNRECOVERABLE_ERROR ] = "An unrecoverable error occurred. The service must shut down.";
		messages[ VDS_S_DISK_PARTIALLY_CLEANED ] = "The disk is not fully cleaned due to I/O error.";
		messages[ VDS_E_DMADMIN_SERVICE_CONNECTION_FAILED ] = "The provider failed to connect to the Logical Disk Management Administrative service.";
		messages[ VDS_E_PROVIDER_INITIALIZATION_FAILED ] = "The provider failed to initialize.";
		messages[ VDS_E_OBJECT_EXISTS ] = "The object already exists.";
		messages[ VDS_E_NO_DISKS_FOUND ] = "No disks were found on the target machine.";
		messages[ VDS_E_PROVIDER_CACHE_CORRUPT ] = "The provider's cache has become corrupt.";
		messages[ VDS_E_DMADMIN_METHOD_CALL_FAILED ] = "A method call to the Logical Disk Management Administrative service failed.";
		messages[ VDS_S_PROVIDER_ERROR_LOADING_CACHE ] = "The provider encountered errors while loading the cache. See the NT Event Log for more information.";
		messages[ VDS_E_PROVIDER_VOL_DEVICE_NAME_NOT_FOUND ] = "The device form of the volume pathname could not be retrieved.";
		messages[ VDS_E_PROVIDER_VOL_OPEN ] = "Failed to open the volume device.";
		messages[ VDS_E_DMADMIN_CORRUPT_NOTIFICATION ] = "A corrupt notification was sent from the Logical Disk Manager Administrative service.";
		messages[ VDS_E_INCOMPATIBLE_FILE_SYSTEM ] = "The file system is incompatible.";
		messages[ VDS_E_INCOMPATIBLE_MEDIA ] = "The media is incompatible.";
		messages[ VDS_E_ACCESS_DENIED ] = "Access is denied.";
		messages[ VDS_E_MEDIA_WRITE_PROTECTED ] = "The media is write protected.";
		messages[ VDS_E_BAD_LABEL ] = "The label is illegal.";
		messages[ VDS_E_CANT_QUICK_FORMAT ] = "Can not quick format the volume.";
		messages[ VDS_E_IO_ERROR ] = "IO error occurred during format.";
		messages[ VDS_E_VOLUME_TOO_SMALL ] = "The volume size is too small.";
		messages[ VDS_E_VOLUME_TOO_BIG ] = "The volume size is too big.";
		messages[ VDS_E_CLUSTER_SIZE_TOO_SMALL ] = "The cluster size is too small.";
		messages[ VDS_E_CLUSTER_SIZE_TOO_BIG ] = "The cluster size is too big.";
		messages[ VDS_E_CLUSTER_COUNT_BEYOND_32BITS ] = "The number of clusters is too big for 32 bit integer.";
		messages[ VDS_E_OBJECT_STATUS_FAILED ] = "The object is in failed status.";
		messages[ VDS_E_VOLUME_INCOMPLETE ] = "All extents for the volume could not be found.";
		messages[ VDS_E_EXTENT_SIZE_LESS_THAN_MIN ] = "The size of the extent is less than the minimum.";
		messages[ VDS_S_UPDATE_BOOTFILE_FAILED ] = "Failed to update the boot configuration data.";
		messages[ VDS_S_BOOT_PARTITION_NUMBER_CHANGE ] = "The boot partition's partition number will change as a result of the operation.";
		messages[ VDS_E_BOOT_PARTITION_NUMBER_CHANGE ] = "The boot partition's partition number will change as a result of the migration operation.";
		messages[ VDS_E_NO_FREE_SPACE ] = "The selected disk does not have enough free space to complete the operation.";
		messages[ VDS_E_ACTIVE_PARTITION ] = "An active partition was detected on the selected disk, and it is not the active partition used to boot the currently running OS.";
		messages[ VDS_E_PARTITION_OF_UNKNOWN_TYPE ] = "Cannot read partition information.";
		messages[ VDS_E_LEGACY_VOLUME_FORMAT ] = "A partition with an unknown type was detected on the selected disk.";
		messages[ VDS_E_NON_CONTIGUOUS_DATA_PARTITIONS ] = "The selected GPT formatted disk contains a partition which is not of type 'PARTITION_BASIC_DATA_GUID', and is both preceeded and followed by a partition of type 'PARTITION_BASIC_DATA_GUID'.";
		messages[ VDS_E_MIGRATE_OPEN_VOLUME ] = "A volume on the selected disk could not be opened.";
		messages[ VDS_E_VOLUME_NOT_ONLINE ] = "The volume is not online.";
		messages[ VDS_E_VOLUME_NOT_HEALTHY ] = "The volume is not healthy.";
		messages[ VDS_E_VOLUME_SPANS_DISKS ] = "The volume spans multiple disks.";
		messages[ VDS_E_REQUIRES_CONTIGUOUS_DISK_SPACE ] = "The volume requires contiguous disk extents.";
		messages[ VDS_E_BAD_PROVIDER_DATA ] = "A provider returned bad data.";
		messages[ VDS_E_PROVIDER_FAILURE ] = "A provider failed to complete an operation.";
		messages[ VDS_S_VOLUME_COMPRESS_FAILED ] = "Failed to compress the volume.";
		messages[ VDS_E_PACK_OFFLINE ] = "The pack is not online.";
		messages[ VDS_E_VOLUME_NOT_A_MIRROR ] = "The volume is not a mirror.";
		messages[ VDS_E_NO_EXTENTS_FOR_VOLUME ] = "No extents were found for the volume.";
		messages[ VDS_E_DISK_NOT_LOADED_TO_CACHE ] = "The disk failed to load to the cache.";
		messages[ VDS_E_INTERNAL_ERROR ] = "Check the event log for errors.";
		messages[ VDS_S_ACCESS_PATH_NOT_DELETED ] = "The access paths on the volume may not be deleted.";
		messages[ VDS_E_PROVIDER_TYPE_NOT_SUPPORTED ] = "The method call is not supported for the specified provider type.";
		messages[ VDS_E_DISK_NOT_ONLINE ] = "This disk is already offline.";
		messages[ VDS_E_DISK_IN_USE_BY_VOLUME ] = "The disk is already in use by the volume.";
		messages[ VDS_S_IN_PROGRESS ] = "The asynchronous operation is in progress.";
		messages[ VDS_E_ASYNC_OBJECT_FAILURE ] = "Failure initializing the asynchronous object.";
		messages[ VDS_E_VOLUME_NOT_MOUNTED ] = "A file system is not mounted on the volume.";
		messages[ VDS_E_PACK_NOT_FOUND ] = "The pack was not found.";
		messages[ VDS_E_IMPORT_SET_INCOMPLETE ] = "Import failed. Attempt to import a subset of the disks in the foreign pack.";
		messages[ VDS_E_DISK_NOT_IMPORTED ] = "A disk in the import's source pack was not imported.";
		messages[ VDS_E_OBJECT_OUT_OF_SYNC ] = "The system's information about the object may not be up to date.";
		messages[ VDS_E_MISSING_DISK ] = "The disk is missing.";
		messages[ VDS_E_DISK_PNP_REG_CORRUPT ] = "The provider's list of PnP registered disks has become corrupt.";
		messages[ VDS_E_LBN_REMAP_ENABLED_FLAG ] = "The provider does not support the LBN REMAP ENABLED volume flag.";
		messages[ VDS_E_NO_DRIVELETTER_FLAG ] = "The provider does not support the NO DRIVELETTER volume flag.";
		messages[ VDS_E_REVERT_ON_CLOSE ] = "REVERT ON CLOSE may only be used with GPT flags HIDDEN, READ ONLY, NO DRIVE LETTER or SHADOW COPY.";
		messages[ VDS_E_REVERT_ON_CLOSE_SET ] = "The REVERT ON CLOSE volume flag is already set for this volume.";
		messages[ VDS_E_IA64_BOOT_MIRRORED_TO_MBR ] = "Not used! You have mirrored your boot volume on a GPT disk, to an MBR disk. You will not be able to boot your machine from the secondary plex.";
		messages[ VDS_S_IA64_BOOT_MIRRORED_TO_MBR ] = "You have mirrored your boot volume on a GPT disk, to an MBR disk. You will not be able to boot your machine from the secondary plex.";
		messages[ VDS_S_UNABLE_TO_GET_GPT_ATTRIBUTES ] = "Unable to retrieve the GPT attributes for this volume, (hidden, read only and no drive letter).";
		messages[ VDS_E_VOLUME_TEMPORARILY_DISMOUNTED ] = "The volume is temporarily dismounted.";
		messages[ VDS_E_VOLUME_PERMANENTLY_DISMOUNTED ] = "The volume is permanently dismounted.";
		messages[ VDS_E_VOLUME_HAS_PATH ] = "The volume still has access path to it.";
		messages[ VDS_E_TIMEOUT ] = "The operation timed out.";
		messages[ VDS_E_REPAIR_VOLUMESTATE ] = "To repair a volume, both the volume and plex must be online, and must not be healthy or rebuilding.";
		messages[ VDS_E_LDM_TIMEOUT ] = "The operation timed out in the Logical Disk Manager Administrative service. Retry the operation.";
		messages[ VDS_E_REVERT_ON_CLOSE_MISMATCH ] = "When clearing volume flags that have been set using revert on close, the same combination of HIDDEN, READ ONLY, NO DRIVE LETTER or SHADOW COPY flags must be passed to both the SetFlags and ClearFlags calls.";
		messages[ VDS_E_RETRY ] = "The operation failed. Retry the operation.";
		messages[ VDS_E_ONLINE_PACK_EXISTS ] = "Create pack operation failed. An online pack already exists.";
		messages[ VDS_S_EXTEND_FILE_SYSTEM_FAILED ] = "The volume was extended successfully but the file system failed to extend.";
		messages[ VDS_E_EXTEND_FILE_SYSTEM_FAILED ] = "The file system failed to extend.";
		messages[ VDS_S_MBR_BOOT_MIRRORED_TO_GPT ] = "You have mirrored your boot volume on an MBR disk, to a GPT disk. You will not be able to boot your machine from the secondary plex.";
		messages[ VDS_E_MAX_USABLE_MBR ] = "Only the first 2TB are usable on large MBR disks. Cannot create partitions beyond the 2TB mark, nor convert the disk to dynamic.";
		messages[ VDS_S_GPT_BOOT_MIRRORED_TO_MBR ] = "You have mirrored your boot volume on a GPT disk, to an MBR disk. You will not be able to boot your machine from the secondary plex.";
		messages[ VDS_E_DISK_NOT_MISSING ] = "The disk is not missing.";
		messages[ VDS_E_NO_VOLUME_LAYOUT ] = "Failed to retrieve the volume's layout. Operations on the volume will fail.";
		messages[ VDS_E_CORRUPT_VOLUME_INFO ] = "The volume's driver information is corrupt. Operations on the volume will fail.";
		messages[ VDS_E_INVALID_ENUMERATOR ] = "The enumerator is corrupted.";
		messages[ VDS_E_DRIVER_INTERNAL_ERROR ] = "Internal error in the volume management driver.";
		messages[ VDS_E_VOLUME_INVALID_NAME ] = "The volume name is invalid.";
		messages[ VDS_S_DISK_IS_MISSING ] = "The disk is missing, not all information could be returned.";
		messages[ VDS_E_CORRUPT_PARTITION_INFO ] = "The disk's partition information is corrupted.";
		messages[ VDS_S_NONCONFORMANT_PARTITION_INFO ] = "The disk's partition information is does not conform to that expected on a dynamic disk.";
		messages[ VDS_E_CORRUPT_EXTENT_INFO ] = "The disk's extent information is corrupted.";
		messages[ VDS_E_DUP_EMPTY_PACK_GUID ] = "An empty pack already exists. Release the existing empty pack before creating another empty pack.";
		messages[ VDS_E_DRIVER_NO_PACK_NAME ] = "The volume management driver did not return a pack name. Internal driver error.";
		messages[ VDS_S_SYSTEM_PARTITION ] = "Warning, there was a failure while checking for the system partition.";
		messages[ VDS_E_BAD_PNP_MESSAGE ] = "The PNP service sent a corrupted notification to the provider.";
		messages[ VDS_E_NO_PNP_DISK_ARRIVE ] = "No disk arrival notification was received.";
		messages[ VDS_E_NO_PNP_VOLUME_ARRIVE ] = "No volume arrival notification was received.";
		messages[ VDS_E_NO_PNP_DISK_REMOVE ] = "No disk removal notification was received.";
		messages[ VDS_E_NO_PNP_VOLUME_REMOVE ] = "No volume removal notification was received.";
		messages[ VDS_E_PROVIDER_EXITING ] = "The provider is exiting.";
		messages[ VDS_E_EXTENT_EXCEEDS_DISK_FREE_SPACE ] = "The specified disk extent size exceeds the size of free disk space.";
		messages[ VDS_E_MEMBER_SIZE_INVALID ] = "The size of the plex member is invalid.";
		messages[ VDS_S_NO_NOTIFICATION ] = "No volume arrival notification was received. Refresh the Disk Management display.";
		messages[ VDS_S_DEFAULT_PLEX_MEMBER_IDS ] = "Defaults have been used for the member ids or plex ids.";
		messages[ VDS_E_INVALID_DISK ] = "This operation is not allowed on an invalid disk. The disk may be invalid because it is corrupted or failing, or it may be invalid because it is OFFLINE.";
		messages[ VDS_E_INVALID_PACK ] = "This operation is not allowed on the invalid disk pack.";
		messages[ VDS_E_VOLUME_ON_DISK ] = "This operation is not allowed on disks with volumes.";
		messages[ VDS_E_DRIVER_INVALID_PARAM ] = "The driver returned an invalid parameter error.";
		messages[ VDS_E_TARGET_PACK_NOT_EMPTY ] = "The target pack is not empty.";
		messages[ VDS_E_CANNOT_SHRINK ] = "The volume cannot be shrunk because the file system does not support it.";
		messages[ VDS_E_MULTIPLE_PACKS ] = "Specified disks are not all from the same pack.";
		messages[ VDS_E_PACK_ONLINE ] = "This operation is not allowed on online packs. The pack must be offline.";
		messages[ VDS_E_INVALID_PLEX_COUNT ] = "The plex count for the volume must be non-zero.";
		messages[ VDS_E_INVALID_MEMBER_COUNT ] = "The member count for the volume must be non-zero.";
		messages[ VDS_E_INVALID_PLEX_ORDER ] = "The plex indexes must be monotonically increasing and begin with zero.";
		messages[ VDS_E_INVALID_MEMBER_ORDER ] = "The member indexes must be monotonically increasing and begin with zero.";
		messages[ VDS_E_INVALID_STRIPE_SIZE ] = "The stripe size must be a multiple of 2, between 512 bytes and 1 MB, for stripe and raid5 volumes. The stripe size must be zero for other volume types.";
		messages[ VDS_E_INVALID_DISK_COUNT ] = "The number of disks specified is invalid for this operation.";
		messages[ VDS_E_INVALID_EXTENT_COUNT ] = "An invalid number of extents was specified for at least one disk.";
		messages[ VDS_E_SOURCE_IS_TARGET_PACK ] = "The source and target packs must be distinct.";
		messages[ VDS_E_VOLUME_DISK_COUNT_MAX_EXCEEDED ] = "The disk count for the volume exceeds the maximum.";
		messages[ VDS_E_CORRUPT_NOTIFICATION_INFO ] = "The driver's notification info is corrupt.";
		messages[ VDS_E_INVALID_PLEX_GUID ] = "GUID_NULL is not a valid plex GUID.";
		messages[ VDS_E_DISK_NOT_FOUND_IN_PACK ] = "The specified disks do not belong to the same pack.";
		messages[ VDS_E_DUPLICATE_DISK ] = "The same disk was specified more than once.";
		messages[ VDS_E_LAST_VALID_DISK ] = "The operation cannot be completed because there is only one valid disk in the pack.";
		messages[ VDS_E_INVALID_SECTOR_SIZE ] = "All disks holding extents for a given volume must have the same sector size, and the sector size must be valid.";
		messages[ VDS_E_ONE_EXTENT_PER_DISK ] = "This call requires the parameters to specify one extent per disk. A single disk cannot contribute to multiple members or plexes of the same volume.";
		messages[ VDS_E_INVALID_BLOCK_SIZE ] = "Neither the volume stripe size or disk sector size was found to be non-zero.";
		messages[ VDS_E_PLEX_SIZE_INVALID ] = "The size of the volume plex is invalid.";
		messages[ VDS_E_NO_EXTENTS_FOR_PLEX ] = "No extents were found for the plex.";
		messages[ VDS_E_INVALID_PLEX_TYPE ] = "The plex type is invalid.";
		messages[ VDS_E_INVALID_PLEX_BLOCK_SIZE ] = "The plex block size must be non-zero.";
		messages[ VDS_E_NO_HEALTHY_DISKS ] = "All of the disks involved in the operation are either missing or failed.";
		messages[ VDS_E_CONFIG_LIMIT ] = "The Logical Disk Management database is full, no more volumes or disks may be configured.";
		messages[ VDS_E_DISK_CONFIGURATION_CORRUPTED ] = "The disk configuration data is corrupted.";
		messages[ VDS_E_DISK_CONFIGURATION_NOT_IN_SYNC ] = "The disk configuration is not in sync with the in-memory configuration.";
		messages[ VDS_E_DISK_CONFIGURATION_UPDATE_FAILED ] = "One or more disks failed to be updated with the new configuration.";
		messages[ VDS_E_DISK_DYNAMIC ] = "The disk is already dynamic.";
		messages[ VDS_E_DRIVER_OBJECT_NOT_FOUND ] = "The object was not found in the driver cache.";
		messages[ VDS_E_PARTITION_NOT_CYLINDER_ALIGNED ] = "The disk layout contains partitions which are not cylinder aligned.";
		messages[ VDS_E_DISK_LAYOUT_PARTITIONS_TOO_SMALL ] = "The disk layout contains partitions which less than the minimum required size.";
		messages[ VDS_E_DISK_IO_FAILING ] = "The IO to the disk is failing.";
		messages[ VDS_E_DYNAMIC_DISKS_NOT_SUPPORTED ] = "Dynamic disks are not supported by this operating system or server configuration. Dynamic disks are not supported on clusters.";
		messages[ VDS_E_FAULT_TOLERANT_DISKS_NOT_SUPPORTED ] = "The fault tolerant disks are not supported by this operating system.";
		messages[ VDS_E_GPT_ATTRIBUTES_INVALID ] = "Invalid GPT attributes were specified.";
		messages[ VDS_E_MEMBER_IS_HEALTHY ] = "The member is not stale or detached.";
		messages[ VDS_E_MEMBER_REGENERATING ] = "The member is regenerating.";
		messages[ VDS_E_PACK_NAME_INVALID ] = "The pack name is invalid.";
		messages[ VDS_E_PLEX_IS_HEALTHY ] = "The plex is not stale or detached.";
		messages[ VDS_E_PLEX_LAST_ACTIVE ] = "The last healthy plex cannot be removed.";
		messages[ VDS_E_PLEX_MISSING ] = "The plex is missing.";
		messages[ VDS_E_MEMBER_MISSING ] = "The member is missing.";
		messages[ VDS_E_PLEX_REGENERATING ] = "The plex is regenerating.";
		messages[ VDS_E_UNEXPECTED_DISK_LAYOUT_CHANGE ] = "An unexpected layout change occurred external to the volume manager.";
		messages[ VDS_E_INVALID_VOLUME_LENGTH ] = "The volume length is invalid.";
		messages[ VDS_E_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE ] = "The volume length is not a multiple of the sector size.";
		messages[ VDS_E_VOLUME_NOT_RETAINED ] = "The volume does not have a retained partition association.";
		messages[ VDS_E_VOLUME_RETAINED ] = "The volume already has a retained partition association.";
		messages[ VDS_E_ALIGN_BEYOND_FIRST_CYLINDER ] = "The specified alignment is beyond the first cylinder.";
		messages[ VDS_E_ALIGN_NOT_SECTOR_SIZE_MULTIPLE ] = "The specified alignment is not a multiple of the sector size.";
		messages[ VDS_E_ALIGN_NOT_ZERO ] = "The specified partition type cannot be created with a non-zero alignment.";
		messages[ VDS_E_CACHE_CORRUPT ] = "The service's cache has become corrupt.";
		messages[ VDS_E_CANNOT_CLEAR_VOLUME_FLAG ] = "The specified volume flag cannot be cleared.";
		messages[ VDS_E_DISK_BEING_CLEANED ] = "The operation is not allowed on a disk that is in the process of being cleaned.";
		messages[ VDS_E_DISK_NOT_CONVERTIBLE ] = "The specified disk is not convertible. CDROMs and DVDs are examples of disks that are not convertable.";
		messages[ VDS_E_DISK_REMOVEABLE ] = "The operation is not supported on removable media.";
		messages[ VDS_E_DISK_REMOVEABLE_NOT_EMPTY ] = "The operation is not supported on a non-empty removable disk.";
		messages[ VDS_E_DRIVE_LETTER_NOT_FREE ] = "The specified drive letter is not free to be assigned.";
		messages[ VDS_E_EXTEND_MULTIPLE_DISKS_NOT_SUPPORTED ] = "Extending the volume onto multiple disks is not supported by this provider.";
		messages[ VDS_E_INVALID_DRIVE_LETTER ] = "The specified drive letter is invalid.";
		messages[ VDS_E_INVALID_DRIVE_LETTER_COUNT ] = "The specified number of drive letters to retrieve is invalid.";
		messages[ VDS_E_INVALID_FS_FLAG ] = "The specified file system flag is invalid.";
		messages[ VDS_E_INVALID_FS_TYPE ] = "The specified file system is invalid.";
		messages[ VDS_E_INVALID_OBJECT_TYPE ] = "The specified object type is invalid.";
		messages[ VDS_E_INVALID_PARTITION_LAYOUT ] = "The specified partition layout is invalid.";
		messages[ VDS_E_INVALID_PARTITION_STYLE ] = "The specified disk's partition style is INVALID. VDS only supports MBR or GPT partition style disks.";
		messages[ VDS_E_INVALID_PARTITION_TYPE ] = "The specified partition type is not valid for this operation.";
		messages[ VDS_E_INVALID_PROVIDER_CLSID ] = "The specified provider clsid cannot be a NULL GUID.";
		messages[ VDS_E_INVALID_PROVIDER_ID ] = "The specified provider id cannot be a NULL GUID.";
		messages[ VDS_E_INVALID_PROVIDER_NAME ] = "The specified provider name is invalid.";
		messages[ VDS_E_INVALID_PROVIDER_TYPE ] = "The specified provider type is invalid.";
		messages[ VDS_E_INVALID_PROVIDER_VERSION_GUID ] = "The specified provider version GUID cannot be a NULL GUID.";
		messages[ VDS_E_INVALID_PROVIDER_VERSION_STRING ] = "The specified provider version string is invalid.";
		messages[ VDS_E_INVALID_QUERY_PROVIDER_FLAG ] = "The specified query provider flag is invalid.";
		messages[ VDS_E_INVALID_SERVICE_FLAG ] = "The specified service flag is invalid.";
		messages[ VDS_E_INVALID_VOLUME_FLAG ] = "The specified volume flag is invalid.";
		messages[ VDS_E_PARTITION_NOT_OEM ] = "The operation is not supported on non-OEM partitions.";
		messages[ VDS_E_PARTITION_PROTECTED ] = "Cannot delete a protected partition without the force protected parameter set.";
		messages[ VDS_E_PARTITION_STYLE_MISMATCH ] = "The specified partition style does not match that of the disk.";
		messages[ VDS_E_PROVIDER_INTERNAL_ERROR ] = "An internal error has occurred in the provider.";
		messages[ VDS_E_SHRINK_SIZE_LESS_THAN_MIN ] = "The specified shrink size is less than then minimum shrink size allowed.";
		messages[ VDS_E_SHRINK_SIZE_TOO_BIG ] = "The specified shrink size is too big and will cause the volume to be smaller than the minimum volume size.";
		messages[ VDS_E_UNRECOVERABLE_PROVIDER_ERROR ] = "An unrecoverable error occurred in a provider. The service must be shut down to regain full functionality.";
		messages[ VDS_E_VOLUME_HIDDEN ] = "Cannot assign a mount point to a hidden volume.";
		messages[ VDS_S_DISMOUNT_FAILED ] = "Failed to dismount the volume after setting the volume flags.";
		messages[ VDS_S_REMOUNT_FAILED ] = "Failed to remount the volume after setting the volume flags.";
		messages[ VDS_E_FLAG_ALREADY_SET ] = "Can't set the specified flag as revert-on-close, because it is already set.";
		messages[ VDS_S_RESYNC_NOTIFICATION_TASK_FAILED ] = "Failure. If the volume is a mirror volume or a raid5 volume, no resynchronization notifications will be sent.";
		messages[ VDS_E_DISTINCT_VOLUME ] = "The input volume id cannot be the id of the volume that is the target of the operation.";
		messages[ VDS_E_VOLUME_NOT_FOUND_IN_PACK ] = "The specified volumes do not belong to the same pack.";
		messages[ VDS_E_PARTITION_NON_DATA ] = "The specified partition is a not a primary or logical volume.";
		messages[ VDS_E_CRITICAL_PLEX ] = "The specified plex is a the current system or boot plex.";
		messages[ VDS_E_VOLUME_SYNCHRONIZING ] = "The operation cannot be completed because the volume is synchronizing.";
		messages[ VDS_E_VOLUME_REGENERATING ] = "The operation cannot be completed because the volume is regenerating.";
		messages[ VDS_S_VSS_FLUSH_AND_HOLD_WRITES ] = "Failed to flush and hold Volume Snapshot Service writes.";
		messages[ VDS_S_VSS_RELEASE_WRITES ] = "Failed to release Volume Snapshot Service writes.";
		messages[ VDS_S_FS_LOCK ] = "Failed to obtain a file system lock.";
		messages[ VDS_E_READONLY ] = "The volume is read only.";
		messages[ VDS_E_INVALID_VOLUME_TYPE ] = "The volume type is invalid for this operation.";
		messages[ VDS_E_BAD_BOOT_DISK ] = "The boot disk experienced failures when the driver attempted to online the pack.";
		messages[ VDS_E_LOG_UPDATE ] = "The driver failed to update the log on at least one disk.";
		messages[ VDS_E_VOLUME_MIRRORED ] = "This operation is not supported on a mirrored volume.";
		messages[ VDS_E_VOLUME_SIMPLE_SPANNED ] = "This operation is only supported on simple or spanned volumes.";
		messages[ VDS_E_NO_VALID_LOG_COPIES ] = "This pack has no valid log copies.";
		messages[ VDS_S_PLEX_NOT_LOADED_TO_CACHE ] = "This plex is present in the driver, but has not yet been loaded to the provider cache. A volume modified notification will be sent by the service once the plex has been loaded to the provider cache.";
		messages[ VDS_E_PLEX_NOT_LOADED_TO_CACHE ] = "This plex is present in the driver, but has not yet been loaded to the provider cache. A volume modified notification will be sent by the service once the plex has been loaded to the provider cache.";
		messages[ VDS_E_PARTITION_MSR ] = "This operation is not supported on MSR partitions.";
		messages[ VDS_E_PARTITION_LDM ] = "This operation is not supported on LDM partitions.";
		messages[ VDS_S_WINPE_BOOTENTRY ] = "The boot entries cannot be updated automatically on WinPE. You may need to manually update the boot entry for any installed operating systems.";
		messages[ VDS_E_ALIGN_NOT_A_POWER_OF_TWO ] = "The specified alignment is not a power of two.";
		messages[ VDS_E_ALIGN_IS_ZERO ] = "The specified alignment is zero.";
		messages[ VDS_E_SHRINK_IN_PROGRESS ] = "A defragmentation or volume shrink operation is already in progress. Only one of these operations can run at a time.";
		messages[ VDS_E_CANT_INVALIDATE_FVE ] = "BitLocker encryption on the volume could not be removed.";
		messages[ VDS_E_FS_NOT_DETERMINED ] = "The default file system could not be determined.";
		messages[ VDS_E_DISK_NOT_OFFLINE ] = "This disk is already online.";
		messages[ VDS_E_FAILED_TO_ONLINE_DISK ] = "The online operation failed.";
		messages[ VDS_E_FAILED_TO_OFFLINE_DISK ] = "The offline operation failed.";
		messages[ VDS_E_BAD_REVISION_NUMBER ] = "The operation could not be completed because the specified revision number is not supported.";
		messages[ VDS_E_SHRINK_USER_CANCELLED ] = "The shrink operation was canceled by the user.";
		messages[ VDS_E_SHRINK_DIRTY_VOLUME ] = "The volume you have selected to shrink may be corrupted. Use Chkdsk to fix the corruption problem, and then try to shrink the volume again.";
		messages[ VDS_E_NAME_NOT_UNIQUE ] = "The name is not unique.";
		messages[ VDS_S_STATUSES_INCOMPLETELY_SET ] = "At least one path status is not set successfully due to a non-fatal error, for example the status conflicts with the current load balance policy.";
		messages[ VDS_E_ADDRESSES_INCOMPLETELY_SET ] = "At least one portal's tunnel address is not set successfully.";
		messages[ VDS_E_SECURITY_INCOMPLETELY_SET ] = "At least one portal's security settings are not set successfully.";
		messages[ VDS_E_TARGET_SPECIFIC_NOT_SUPPORTED ] = "The initiator does not support setting target-specific shared secrets.";
		messages[ VDS_E_INITIATOR_SPECIFIC_NOT_SUPPORTED ] = "The target does not support setting initiator-specific shared secrets.";
		messages[ VDS_E_ISCSI_LOGIN_FAILED ] = "An iSCSI login session could not be established.";
		messages[ VDS_E_ISCSI_LOGOUT_FAILED ] = "The attempt to log out from the specified iSCSI session failed.";
		messages[ VDS_E_ISCSI_SESSION_NOT_FOUND ] = "The specified iSCSI session with a connection matching the specified target, target portal, and/or initiator portal could not be found.";
		messages[ VDS_E_ASSOCIATED_LUNS_EXIST ] = "LUNs are associated with the specified target and must first be deassociated before the target can be deleted.";
		messages[ VDS_E_ASSOCIATED_PORTALS_EXIST ] = "Portals are associated with the specified portal group and must first be deassociated before the portal group can be deleted.";
		messages[ VDS_E_NO_DISCOVERY_DOMAIN ] = "The initiator does not exist in a iSNS discovery domain.";
		messages[ VDS_E_MULTIPLE_DISCOVERY_DOMAINS ] = "The initiator exists in more than one iSNS discovery domain.";
		messages[ VDS_E_NO_DISK_PATHNAME ] = "Failed to retrieve the disk's pathname. Some operations on the disk may fail.";
		messages[ VDS_E_ISCSI_LOGOUT_INCOMPLETE ] = "At least one session did not logout successfully.";
		messages[ VDS_E_NO_VOLUME_PATHNAME ] = "Failed to retrieve the volume's pathname.";
		messages[ VDS_E_PROVIDER_CACHE_OUTOFSYNC ] = "The provider's cache is not in-sync with the driver cache.";
		messages[ VDS_E_NO_IMPORT_TARGET ] = "No import target was set for this subsystem in the registry.";
		messages[ VDS_S_ALREADY_EXISTS ] = "The object already exists and does not need to be further created or added.";
		messages[ VDS_S_PROPERTIES_INCOMPLETE ] = "Unable to retrieve all properties for this object. Some attributes may be incomplete or missing.";
		messages[ VDS_S_ISCSI_PERSISTENT_LOGIN_MAY_NOT_BE_REMOVED ] = "If a persistent login was set up for the target, it may not have been removed. Check the iSCSI Initiator Control Panel to remove it if necessary.";
		messages[ VDS_S_ISCSI_LOGIN_ALREAD_EXISTS ] = "Login failed because the target is already logged in.";
		messages[ VDS_E_UNABLE_TO_FIND_BOOT_DISK ] = "A system error occurred while retrieving the boot disk information.";
		messages[ VDS_E_INCORRECT_BOOT_VOLUME_EXTENT_INFO ] = "Multiple disk extents reported for the boot volume - system error.";
		messages[ VDS_E_GET_SAN_POLICY ] = "A driver error was reported when getting the SAN policy.";
		messages[ VDS_E_SET_SAN_POLICY ] = "A driver error was reported when setting the SAN policy.";
		messages[ VDS_E_BOOT_DISK ] = "Disk attributes may not be changed on the boot disk.";
		messages[ VDS_S_DISK_MOUNT_FAILED ] = "Failed to mount one or more of the volumes on the disk.";
		messages[ VDS_S_DISK_DISMOUNT_FAILED ] = "Failed to dismount one or more of the volumes on the disk.";
		messages[ VDS_E_DISK_IS_OFFLINE ] = "The operation is not allowed on a disk that is offline.";
		messages[ VDS_E_DISK_IS_READ_ONLY ] = "The operation is not allowed on a disk that is read only.";
		messages[ VDS_E_PAGEFILE_DISK ] = "The operation is not allowed on a disk that contains a pagefile volume.";
		messages[ VDS_E_HIBERNATION_FILE_DISK ] = "The operation is not allowed on a disk that contains a hibernation file volume.";
		messages[ VDS_E_CRASHDUMP_DISK ] = "The operation is not allowed on a disk that contains a crashdump file volume.";
		messages[ VDS_E_UNABLE_TO_FIND_SYSTEM_DISK ] = "A system error occurred while retrieving the system disk information.";
		messages[ VDS_E_INCORRECT_SYSTEM_VOLUME_EXTENT_INFO ] = "Multiple disk extents reported for the system volume - system error.";
		messages[ VDS_E_SYSTEM_DISK ] = "Disk attributes may not be changed on the current system disk or BIOS disk 0.";
		messages[ VDS_E_VOLUME_SHRINK_FVE_LOCKED ] = "The volume could not be shrunk because it is locked by BitLocker. Unlock the volume and try again.";
		messages[ VDS_E_VOLUME_SHRINK_FVE_CORRUPT ] = "The volume could not be shrunk because it is locked due to a BitLocker error. Use BitLocker tools to recover the volume and try again.";
		messages[ VDS_E_VOLUME_SHRINK_FVE_RECOVERY ] = "The volume could not be shrunk because it is marked for BitLocker recovery. Use BitLocker tools to recover the volume and try again.";
		messages[ VDS_E_VOLUME_SHRINK_FVE ] = "The volume could not be shrunk because it is encrypted by BitLocker and Fveapi.dll could not be loaded to determine its status. For this operation to succeed, Fveapi.dll must be available in %SystemRoot%\\System32\\.";
		messages[ VDS_E_SHRINK_OVER_DATA ] = "The SHRINK operation against the selected LUN cannot be completed. Completing the operation using the specified parameters will overwrite volumes containing user data.";
		messages[ VDS_E_INVALID_SHRINK_SIZE ] = "The SHRINK operation against the selected LUN cannot be completed. The specified size is greater than the size of the LUN.";
		messages[ VDS_E_LUN_DISK_MISSING ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the disk associated with the LUN is MISSING.";
		messages[ VDS_E_LUN_DISK_FAILED ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the disk associated with the LUN is FAILED.";
		messages[ VDS_E_LUN_DISK_NOT_READY ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the disk associated with the LUN is NOT READY.";
		messages[ VDS_E_LUN_DISK_NO_MEDIA ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the disk associated with the LUN is NO MEDIA.";
		messages[ VDS_E_LUN_NOT_READY ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the LUN is NOT READY.";
		messages[ VDS_E_LUN_OFFLINE ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the LUN is OFFLINE.";
		messages[ VDS_E_LUN_FAILED ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the LUN is FAILED.";
		messages[ VDS_E_VOLUME_EXTEND_FVE_LOCKED ] = "The volume could not be extended because it is locked by BitLocker. Unlock the volume and retry the operation.";
		messages[ VDS_E_VOLUME_EXTEND_FVE_CORRUPT ] = "The volume could not be extended because it is locked due to a BitLocker error. Use BitLocker tools to recover the volume and retry the operation.";
		messages[ VDS_E_VOLUME_EXTEND_FVE_RECOVERY ] = "The volume could not be extended because it is marked for BitLocker recovery. Use BitLocker tools to recover the volume and retry the operation.";
		messages[ VDS_E_VOLUME_EXTEND_FVE ] = "The volume could not be extended because it is encrypted by BitLocker and Fveapi.dll could not be loaded to determine its status. For this operation to succeed, Fveapi.dll must be available in %SystemRoot%\\System32\\.";
		messages[ VDS_E_SECTOR_SIZE_ERROR ] = "The sector size must be non-zero, a power of 2, and less than the maximum sector size.";
		messages[ VDS_E_TARGET_PORTAL_NOT_FOUND ] = "The target portal was not found. For calls to GetPathInfo(), the target portal is associated with the path end point.";
		messages[ VDS_E_INVALID_PORT_PATH ] = "The path returned for the port is invalid. Either it has an incorrect port type specified, or, the HBA port properties structure is NULL.";
		messages[ VDS_E_INVALID_ISCSI_TARGET_NAME ] = "An invalid iSCSI target name was returned from the provider.";
		messages[ VDS_E_SET_TUNNEL_MODE_OUTER_ADDRESS ] = "Call to set the iSCSI tunnel mode outer address failed.";
		messages[ VDS_E_ISCSI_GET_IKE_INFO ] = "Call to get the iSCSI IKE info failed.";
		messages[ VDS_E_ISCSI_SET_IKE_INFO ] = "Call to set the iSCSI IKE info failed.";
		messages[ VDS_E_SUBSYSTEM_ID_IS_NULL ] = "The provider returned a NULL subsystem identification string.";
		messages[ VDS_E_ISCSI_INITIATOR_NODE_NAME ] = "Failed to get the iSCSI initiator node name.";
		messages[ VDS_E_ISCSI_GROUP_PRESHARE_KEY ] = "Failed to set iSCSI group preshared key.";
		messages[ VDS_E_ISCSI_CHAP_SECRET ] = "Failed to set iSCSI initiator CHAP secret.";
		messages[ VDS_E_INVALID_IP_ADDRESS ] = "An invalid IP address was encountered.";
		messages[ VDS_E_REBOOT_REQUIRED ] = "A reboot is required before any further operations may be initiated. If you do not reboot, machine behavior and machine state, are undefined for any further operations.";
		messages[ VDS_E_VOLUME_GUID_PATHNAME_NOT_ALLOWED ] = "Volume GUID pathnames are not valid input to this method.";
		messages[ VDS_E_BOOT_PAGEFILE_DRIVE_LETTER ] = "Assigning or removing drive letters on the current boot or pagefile volume is not allowed.";
		messages[ VDS_E_DELETE_WITH_CRITICAL ] = "Delete is not allowed on the current boot, system, pagefile, crashdump or hibernation volume.";
		messages[ VDS_E_CLEAN_WITH_DATA ] = "The FORCE parameter must be set to TRUE in order to clean a disk that contains a data volume.";
		messages[ VDS_E_CLEAN_WITH_OEM ] = "The FORCE parameter must be set to TRUE in order to clean a disk that contains an OEM volume.";
		messages[ VDS_E_CLEAN_WITH_CRITICAL ] = "Clean is not allowed on the disk containing the current boot, system, pagefile, crashdump or hibernation volume.";
		messages[ VDS_E_FORMAT_CRITICAL ] = "Format is not allowed on the current boot, system, pagefile, crashdump or hibernation volume.";
		messages[ VDS_E_NTFS_FORMAT_NOT_SUPPORTED ] = "The NTFS file system format is not supported on this volume.";
		messages[ VDS_E_FAT32_FORMAT_NOT_SUPPORTED ] = "The FAT32 file system format is not supported on this volume.";
		messages[ VDS_E_FAT_FORMAT_NOT_SUPPORTED ] = "The FAT file system format is not supported on this volume.";
		messages[ VDS_E_FORMAT_NOT_SUPPORTED ] = "The volume is not formattable.";
		messages[ VDS_E_COMPRESSION_NOT_SUPPORTED ] = "The specified file system does not support compression.";
		messages[ VDS_E_VDISK_NOT_OPEN ] = "The virtual disk object has not been open yet.";
		messages[ VDS_E_VDISK_INVALID_OP_STATE ] = "The requested operation cannot be performed on the virtual disk object, because it is not in a state that permits it.";
		messages[ VDS_E_INVALID_PATH ] = "The path returned for the LUN is invalid. It has an incorrect path type specified.";
		messages[ VDS_E_INVALID_ISCSI_PATH ] = "The path returned for the LUN is invalid. Either it has an incorrect path type specified, or, the initiator portal properties structure is NULL.";
		messages[ VDS_E_SHRINK_LUN_NOT_UNMASKED ] = "The SHRINK operation against the selected LUN cannot be completed. The LUN is not unmasked to the local server.";
		messages[ VDS_E_LUN_DISK_READ_ONLY ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the disk associated with the LUN is READ ONLY.";
		messages[ VDS_E_LUN_UPDATE_DISK ] = "The operation against the selected LUN completed, but there was a failure updating the status of the disk associated with the lun. Call REFRESH to retry the status update for the disk.";
		messages[ VDS_E_LUN_DYNAMIC ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the disk associated with the LUN is DYNAMIC.";
		messages[ VDS_E_LUN_DYNAMIC_OFFLINE ] = "The SHRINK operation against the selected LUN cannot be completed. The current state of the disk associated with the LUN is DYNAMIC OFFLINE.";
		messages[ VDS_E_LUN_SHRINK_GPT_HEADER ] = "The SHRINK operation against the selected LUN cannot be completed. The disk has the GPT partitioning format. The specified new lun size does not allow space for a new GPT backup header to be created. Please increase the resulting lun size.";
		messages[ VDS_E_MIRROR_NOT_SUPPORTED ] = "Mirrored volumes are not supported by this operating system.";
		messages[ VDS_E_RAID5_NOT_SUPPORTED ] = "RAID-5 volumes are not supported by this operating system.";
		messages[ VDS_E_DISK_NOT_CONVERTIBLE_SIZE ] = "The specified disk is not convertible because the size is less than the minimum size required for GPT disks.";
		messages[ VDS_E_OFFLINE_NOT_SUPPORTED ] = "The volume does not support offlining.";
		messages[ VDS_E_VDISK_PATHNAME_INVALID ] = "The pathname for a virtual disk must be fully qualified.";
		messages[ VDS_E_EXTEND_TOO_MANY_CLUSTERS ] = "The volume cannot be extended because the number of clusters will exceed the maximum number of clusters supported by the file system.";
		messages[ VDS_E_EXTEND_UNKNOWN_FILESYSTEM ] = "The volume cannot be extended because the volume does not contain a recognized file system.";
		messages[ VDS_E_SHRINK_UNKNOWN_FILESYSTEM ] = "The volume cannot be shrunk because the volume does not contain a recognized file system.";
		messages[ VDS_E_VD_DISK_NOT_OPEN ] = "The requested operation requires that the virtual disk be opened.";
		messages[ VDS_E_VD_DISK_IS_EXPANDING ] = "The requested operation cannot be performed while the virtual disk is expanding.";
		messages[ VDS_E_VD_DISK_IS_COMPACTING ] = "The requested operation cannot be performed while the virtual disk is compacting.";
		messages[ VDS_E_VD_DISK_IS_MERGING ] = "The requested operation cannot be performed while the virtual disk is merging.";
		messages[ VDS_E_VD_IS_ATTACHED ] = "The requested operation cannot be performed while the virtual disk is attached.";
		messages[ VDS_E_VD_DISK_ALREADY_OPEN ] = "The virtual disk is already open and cannot be opened a second time. Please close all clients that may have opened the virtual disk and retry.";
		messages[ VDS_E_VD_DISK_ALREADY_EXPANDING ] = "The virtual disk is already in the process of expanding.";
		messages[ VDS_E_VD_ALREADY_COMPACTING ] = "The virtual disk is already in the process of compacting.";
		messages[ VDS_E_VD_ALREADY_MERGING ] = "The virtual disk is already in the process of merging.";
		messages[ VDS_E_VD_ALREADY_ATTACHED ] = "The virtual disk is already attached.";
		messages[ VDS_E_VD_ALREADY_DETACHED ] = "The virtual disk is already detached.";
		messages[ VDS_E_VD_NOT_ATTACHED_READONLY ] = "The requested operation requires that the virtual disk be attached read only.";
		messages[ VDS_E_VD_IS_BEING_ATTACHED ] = "The requested operation cannot be performed while the virtual disk is being attached.";
		messages[ VDS_E_VD_IS_BEING_DETACHED ] = "The requested operation cannot be performed while the virtual disk is being detached.";
		messages[ VDS_E_NO_POOL_CREATED ] = "No pool is created.";
		messages[ VDS_E_NO_MAINTENANCE_MODE ] = "The specified disk or volume is managed by the Microsoft Failover Clustering component. The disk must be in cluster maintenance mode and the cluster resource status must be online to perform this operation.";
		messages[ VDS_E_BLOCK_CLUSTERED ] = "The specified disk or volume is managed by Microsoft Failover Clustering. The disk must be removed from the cluster to perform this operation.";
		messages[ VDS_E_DISK_HAS_BANDS ] = "The disk could not be converted to dynamic because security is enabled on one or more partitions.";
		messages[ VDS_E_INVALID_STATE ] = "The requested operation cannot be performed on the object, because it is not in a state that permits it. Call Refresh and retry the operation.";
		messages[ VDS_E_REFS_FORMAT_NOT_SUPPORTED ] = "The ReFS file system format is not supported on this volume.";

		messages.Rehash();
	}

	auto p = messages.Lookup( hr );
	if( NULL == p )
		return NULL;
	return p->m_value;
}

CStringW ErrorMessageW( HRESULT hr )
{
	CStringW res;

	// VDS error
	const char* const vdsMessage = vdsCode( hr );
	if( NULL != vdsMessage )
	{
		res.Format( L"%S", vdsMessage );
		return res;
	}

	// System error
	LPVOID lpMsgBuf;
	if( FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPTSTR)&lpMsgBuf, 0, NULL ) )
	{
		res.Format( L"0x%.8X %s", hr, lpMsgBuf );
		LocalFree( lpMsgBuf );
		return res;
	}

	// Unknown error
	res.Format( L"Unknown error 0x%.8X", hr );
	return res;
}